// socket多进程通讯服务端
#include "../_public.h"

CLogFile logfile;      // 服务程序的运行日志
CTcpServer TcpServer;  // 创建服务端对象

void FathEXIT(int sig);
void ChldEXIT(int sig);

int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		printf("Using:./demo10 port logfile\nExample:./demo10 5005 /tmp/demo10.log\n\n");
		return -1;
	}

	CloseIOAndSignal();
	signal(SIGINT, FathEXIT);
	signal(SIGTERM, FathEXIT);

	if (logfile.Open(argv[2],"a+")==false) { 
		printf("logfile.Open(%s) failed.\n",argv[2]); 
		return -1; 
	}

	// 服务端初始化
	if( TcpServer.InitServer(atoi(argv[1])) == false ){
		logfile.Write("TcpServer.InitServer(%s) failed.\n", argv[1]);
		return -1;
	}
	while (true)
	{
		// 等待客户端的连接请求
		if( TcpServer.Accept() == false ){
			logfile.Write("TcpServer.Accept() failed.\n");
			// return -1;
			FathEXIT(-1);
		}
		logfile.Write("客户端（%s）已连接\n", TcpServer.GetIP());

// logfile.Write("listenfd=%d, connfd=%d\n", TcpServer.m_listenfd, TcpServer.m_connfd);
		
		// 在服务器关闭connfd（客户端），在客户端关闭listenfd，以节省资源
		if(fork() > 0) {
			TcpServer.CloseClient();
			continue;
		}

		signal(SIGINT, ChldEXIT);
		signal(SIGTERM, ChldEXIT);
		
		TcpServer.CloseListen();
// logfile.Write("listenfd=%d, connfd=%d\n", TcpServer.m_listenfd, TcpServer.m_connfd);
// sleep(100);

		// 子进程与客户端通讯，处理业务
		char buffer[102400];

		// 第5步：与客户端通讯，接收客户端发过来的报文后，回复ok。
		while (1)
		{
			memset(buffer, 0, sizeof(buffer));
			if ( TcpServer.Read(buffer) == false ) // 接收客户端的请求报文。
			{
				break;
			}
			logfile.Write("接收：%s\n", buffer);

			// exit(0);

			strcpy(buffer, "ok");
			if ( TcpServer.Write(buffer) == false ) // 向客户端发送响应结果。
			{
				perror("send");
				break;
			}
			logfile.Write("发送：%s\n", buffer);
		}

		// return 0;
		ChldEXIT(0);
	}
}

void FathEXIT(int sig){
	// 以下代码是为了防止信号处理函数在执行的过程中被信号中断
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	logfile.Write("父进程退出,sig=%d\n", sig);
	TcpServer.CloseListen();// 关闭监听的socket
	kill(0,15);				// 通知全部的子进程退出
	exit(0);				// 父进程退出
}

void ChldEXIT(int sig){
	// 以下代码是为了防止信号处理函数在执行的过程中被信号中断
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	logfile.Write("子进程退出,sig=%d\n", sig);
	TcpServer.CloseClient();
	exit(0);
}